/*
 *
 * Created on 1 août 2008, 23:00
 */

package application.Forms;

import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.SwingUtilities;
import javax.swing.ImageIcon;

import java.awt.Dimension;
import java.awt.Toolkit;
import java.awt.event.KeyEvent;

import org.apache.log4j.*;

import library.Choosers.*;
import library.JpegNodes.*;
import library.Logs.*;
import library.RemoteControl.*;
import library.Thread.*;
import library.Configuration.*;
import library.Constants.*;
import library.Forms.*;

/**
 * This frame is the body of the application
 * 
 * The whole project has been designed to offer the choice :
 *  - to implement an applet that manages the GUI capabilities
 *  - to implement an application that manages the GUI capabilities
 *  - to implement an application without GUI capabilities
 * 
 * The processing is the same for all modes (SimpleExif library)
 * 
 * The Interface_Form interface defines the interface to respect to implement
 * the graphical frame (whether application or applet)
 * 
 * @author  JNC
 */
@SuppressWarnings("serial")
public class JFrame_Form extends javax.swing.JFrame implements FormInterface {
 
    /**
     * The log4j log
     */
    private final Logger _logger = Logger.getLogger(JFrame_Form.class);
    
    /**
     * Proposed default directory, that contains the jpeg files
     */
    private final String _DEFAULT_DIRECTORY = Configuration.getPathProperty(Constants._DEFAULTDIRECTORY_KEYWORD);

    /**
     * Reference to the remote control
     * If the processing part of the application needs to interact with the GUI,
     * all requests must be adressed through the remote control
     */
    private FrameRemoteControl _remoteControl;
    
    /**
     * Constructor
     * Performs the following actions :
     * <ul>
     * <li> creates new form,
     * <li> tells the log4j log which text area must receive the logs,
     * <li> moves the frame to the center of the window,
     * </ul>
     */
    public JFrame_Form() throws UnknownClassException {
        
        // creates a remote control and registers into it
        setRemoteControl(new FrameRemoteControl());
        
        // change to Windows Look And Feel
        changeToWindowsLookAndFeel();
        
        // initialize the components
        initComponents();
        
        // set the text area for the logging capability
        TextAreaAppender.setParameters(jLogTextArea, _remoteControl);
        
        // initializes labels
        initializeLabels();
        
        // move the frame to the center of the windows
        moveFrameToCenter();
        
        // ask the focus to be set on the GO/CANCEL button
        // must be called after the coponent has been displayed on the screen
        // may be a good idea to call it as the last action afer the windows is
        // display and before he control is turned over to the user
        jGoCancelButton.requestFocusInWindow();
        
        _logger.info("Choose a directory, an action, and then press Go!");
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("deprecation")
	private void initComponents() {

        jChooseActionButtonGroup = new javax.swing.ButtonGroup();
        jGoCancelButton = new javax.swing.JButton();
        jChooseDirectoryLabel = new javax.swing.JLabel();
        jChooseDirectoryButton = new javax.swing.JButton();
        jDirectoryPathTextField = new javax.swing.JTextField();
        jSeparator1 = new javax.swing.JSeparator();
        jChooseActionLabel = new javax.swing.JLabel();
        jRenameNewJpegFilesRadioButton = new javax.swing.JRadioButton();
        jCheckJpegFilesRadioButton = new javax.swing.JRadioButton();
        jRecursiveCheckBox = new javax.swing.JCheckBox();
        jSeparator2 = new javax.swing.JSeparator();
        jGoLabel = new javax.swing.JLabel();
        jProgressBar = new javax.swing.JProgressBar();
        jShowPicturesCheckBox = new javax.swing.JCheckBox();
        jShowPicturesLabel = new javax.swing.JLabel();
        jShowLabelsCheckBox = new javax.swing.JCheckBox();
        jFileNameBeforeLabel = new javax.swing.JLabel();
        jDigitalizationDateLabel = new javax.swing.JLabel();
        jTitleLabel = new javax.swing.JLabel();
        jFileNameAfterLabel = new javax.swing.JLabel();
        jLogScrollPane = new javax.swing.JScrollPane();
        jLogTextArea = new javax.swing.JTextArea();
        jDigitalizationDateLabel2 = new javax.swing.JLabel();

        setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
        setCursor(new java.awt.Cursor(java.awt.Cursor.DEFAULT_CURSOR));
        addWindowListener(new java.awt.event.WindowAdapter() {
            public void windowClosed(java.awt.event.WindowEvent evt) {
                formWindowClosed(evt);
            }
        });

        jGoCancelButton.setText("_");
        jGoCancelButton.setNextFocusableComponent(jChooseDirectoryButton);
        jGoCancelButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jGoCancelButtonActionPerformed(evt);
            }
        });

        jChooseDirectoryLabel.setText("1.Choose Directory");

        jChooseDirectoryButton.setText("Select directory");
        jChooseDirectoryButton.setNextFocusableComponent(jDirectoryPathTextField);
        jChooseDirectoryButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jChooseDirectoryButtonActionPerformed(evt);
            }
        });

        jDirectoryPathTextField.setText("Not assigned");
        jDirectoryPathTextField.setNextFocusableComponent(jGoCancelButton);
        jDirectoryPathTextField.addFocusListener(new java.awt.event.FocusAdapter() {
            public void focusGained(java.awt.event.FocusEvent evt) {
                jDirectoryPathTextFieldFocusGained(evt);
            }
        });
        jDirectoryPathTextField.addKeyListener(new java.awt.event.KeyAdapter() {
            public void keyTyped(java.awt.event.KeyEvent evt) {
                jDirectoryPathTextFieldKeyTyped(evt);
            }
        });

        jChooseActionLabel.setText("2. Choose action");

        jChooseActionButtonGroup.add(jRenameNewJpegFilesRadioButton);
        jRenameNewJpegFilesRadioButton.setSelected(true);
        jRenameNewJpegFilesRadioButton.setText("Rename new Jpeg files");

        jChooseActionButtonGroup.add(jCheckJpegFilesRadioButton);
        jCheckJpegFilesRadioButton.setText("Check Jpeg files");
        jCheckJpegFilesRadioButton.setEnabled(false);

        jRecursiveCheckBox.setText("Recursive ?");

        jGoLabel.setText("3. Go !");

        jShowPicturesCheckBox.setSelected(true);
        jShowPicturesCheckBox.setText("Show thumbnails");
        jShowPicturesCheckBox.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jShowPicturesCheckBoxActionPerformed(evt);
            }
        });

        jShowPicturesLabel.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
        jShowPicturesLabel.setText("Not assigned");

        jShowLabelsCheckBox.setSelected(true);
        jShowLabelsCheckBox.setText("Show details");
        jShowLabelsCheckBox.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jShowLabelsCheckBoxActionPerformed(evt);
            }
        });

        jFileNameBeforeLabel.setText("Not assigned");

        jDigitalizationDateLabel.setText("Not assigned");

        jTitleLabel.setText("Not assigned");

        jFileNameAfterLabel.setText("Not assigned");

        jLogScrollPane.setHorizontalScrollBarPolicy(javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
        jLogScrollPane.setVerticalScrollBarPolicy(javax.swing.ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
        jLogScrollPane.addMouseMotionListener(new java.awt.event.MouseMotionAdapter() {
            public void mouseMoved(java.awt.event.MouseEvent evt) {
                jLogScrollPaneMouseMoved(evt);
            }
        });

        jLogTextArea.setColumns(20);
        jLogTextArea.setEditable(false);
        jLogTextArea.setFont(new java.awt.Font("Monospaced", 0, 10));
        jLogTextArea.setLineWrap(true);
        jLogTextArea.setRows(5);
        jLogTextArea.setWrapStyleWord(true);
        jLogScrollPane.setViewportView(jLogTextArea);

        jDigitalizationDateLabel2.setText("Not assigned");

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addComponent(jChooseDirectoryLabel, javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup()
                        .addGap(24, 24, 24)
                        .addComponent(jChooseDirectoryButton)
                        .addGap(54, 54, 54)
                        .addComponent(jDirectoryPathTextField, javax.swing.GroupLayout.DEFAULT_SIZE, 604, Short.MAX_VALUE))
                    .addComponent(jSeparator1, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 789, Short.MAX_VALUE)
                    .addComponent(jSeparator2, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 789, Short.MAX_VALUE)
                    .addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup()
                        .addComponent(jChooseActionLabel)
                        .addGap(105, 105, 105)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(jRenameNewJpegFilesRadioButton)
                            .addComponent(jCheckJpegFilesRadioButton)
                            .addComponent(jRecursiveCheckBox))
                        .addGap(42, 42, 42))
                    .addGroup(layout.createSequentialGroup()
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addGroup(layout.createSequentialGroup()
                                .addGap(23, 23, 23)
                                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                    .addComponent(jGoCancelButton, javax.swing.GroupLayout.PREFERRED_SIZE, 107, javax.swing.GroupLayout.PREFERRED_SIZE)
                                    .addComponent(jShowPicturesCheckBox)
                                    .addComponent(jShowPicturesLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE)))
                            .addComponent(jGoLabel))
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addGroup(layout.createSequentialGroup()
                                .addGap(56, 56, 56)
                                .addComponent(jShowLabelsCheckBox)
                                .addGap(28, 28, 28)
                                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                    .addComponent(jFileNameBeforeLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 215, javax.swing.GroupLayout.PREFERRED_SIZE)
                                    .addComponent(jDigitalizationDateLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 215, javax.swing.GroupLayout.PREFERRED_SIZE)
                                    .addComponent(jTitleLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 215, javax.swing.GroupLayout.PREFERRED_SIZE))
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                .addComponent(jFileNameAfterLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 242, javax.swing.GroupLayout.PREFERRED_SIZE)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 27, Short.MAX_VALUE))
                            .addGroup(layout.createSequentialGroup()
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                    .addComponent(jLogScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 653, Short.MAX_VALUE)
                                    .addComponent(jProgressBar, javax.swing.GroupLayout.DEFAULT_SIZE, 653, Short.MAX_VALUE))))))
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                        .addContainerGap()
                        .addComponent(jChooseDirectoryLabel)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                            .addComponent(jChooseDirectoryButton)
                            .addComponent(jDirectoryPathTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                        .addGap(18, 18, 18)
                        .addComponent(jSeparator1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                            .addComponent(jChooseActionLabel)
                            .addComponent(jRenameNewJpegFilesRadioButton))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jCheckJpegFilesRadioButton)
                        .addGap(11, 11, 11)
                        .addComponent(jRecursiveCheckBox)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addComponent(jSeparator2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addGroup(layout.createSequentialGroup()
                                .addComponent(jGoLabel)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                .addComponent(jGoCancelButton)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                .addComponent(jShowPicturesCheckBox))
                            .addGroup(layout.createSequentialGroup()
                                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                                    .addComponent(jShowLabelsCheckBox)
                                    .addComponent(jFileNameBeforeLabel))
                                .addGap(18, 18, 18)
                                .addComponent(jTitleLabel))))
                    .addGroup(layout.createSequentialGroup()
                        .addGap(192, 192, 192)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                            .addComponent(jDigitalizationDateLabel)
                            .addComponent(jFileNameAfterLabel))))
                .addGap(5, 5, 5)
                .addComponent(jProgressBar, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                        .addGap(16, 16, 16)
                        .addComponent(jShowPicturesLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addGap(194, 194, 194))
                    .addGroup(layout.createSequentialGroup()
                        .addGap(30, 30, 30)
                        .addComponent(jLogScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 269, Short.MAX_VALUE)
                        .addContainerGap())))
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

/**
 * Starts all necessary actions when the user pushes the Choose Directory button
 * This methods performs the following actions :
 * <ul>
 * <li> starts the directory chooser,
 * <li> sets the choosen directory path to the appropriate label.
 * </ul>
 * @param evt
 * Mandatory Java-dependent variable 
 */
private void jChooseDirectoryButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jChooseDirectoryButtonActionPerformed
    
    // open the JpegDirectory Chooser
    DirectoryChooser chooser = new DirectoryChooser(jDirectoryPathTextField.getText());    
    
    _logger.debug("Will start directory chooser");
    String directoryPath = chooser.showOpenDialogAndReturnDirectoryPath(this);
    
    if (directoryPath == null) {
        // no selected directory
        _logger.warn("The user selected no directory");
    } else {
        _logger.info("The selected directory is " + directoryPath);
        
        // set the text in the label
        jDirectoryPathTextField.setText(directoryPath);
    }
    
    // warn the user
    _logger.info("Nothing will be processed until you press the Go! button");
}//GEN-LAST:event_jChooseDirectoryButtonActionPerformed

/**
 * Starts all necessary actions when the user pushes the Go! button
 * The user can select one of the following actions through check boxes
 * @param evt
 * Mandatory Java dependent variable
 */
private void jGoCancelButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jGoCancelButtonActionPerformed

    ActionTypeEnum action;
    
    // determines the state of the GO button
    if (jGoCancelButton.getText().equals(_LABEL_GO)) {
        // pressing the button means GO
        // ----------------------------
        _logger.debug("The user pressed the Go! button");    
        
        // changes the label of the button
        jGoCancelButton.setText(_LABEL_CANCEL);
        
        // determines the requested action
        action = selectedAction();
    
        if (action == ActionTypeEnum.None) {
            _logger.warn("No action selected !");
        } else {
            // starts the thread
            try {
                new ProcessingThread(jDirectoryPathTextField.getText(),
                                    action,
                                    jRecursiveCheckBox.isSelected(),
                                    _remoteControl).start();
            }
            catch(UnknownClassException exception) {
                _logger.debug("Exception_UnknownClassException caught while creating Class_ProcessingThread : " + exception);
            }
        }
    } else {
        // pressing the button means CANCEL
        // --------------------------------
        _logger.debug("The user pressed the Cancel! button");
        
        // request the thread to stop processing
        _remoteControl.requestProcessingThreadToStop();
        
        // It is not time yet to set the text of the GO/CANCEL button to GO
        // The text will be reinitialized only when the processing thread will stop
        // It is time however to desactivate the GO/CANCEL button
        // The button will be reactivated when the processing thread will stop
        _remoteControl.activateGoCancelButton(false);
    }
}//GEN-LAST:event_jGoCancelButtonActionPerformed

private void jShowPicturesCheckBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jShowPicturesCheckBoxActionPerformed
    if (!jShowPicturesCheckBox.isSelected()) {
        jShowPicturesLabel.setIcon(null);
    }
}//GEN-LAST:event_jShowPicturesCheckBoxActionPerformed

private void jShowLabelsCheckBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jShowLabelsCheckBoxActionPerformed
    if (!jShowLabelsCheckBox.isSelected()) {
        reinitLabels();
    }
}//GEN-LAST:event_jShowLabelsCheckBoxActionPerformed

private void formWindowClosed(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_formWindowClosed
    _logger.debug("Windows closed : will stop processing thread");
    
    if (_remoteControl != null) {
        _remoteControl.requestProcessingThreadToStop();
    }
}//GEN-LAST:event_formWindowClosed

private void jDirectoryPathTextFieldFocusGained(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_jDirectoryPathTextFieldFocusGained
    // a mouse click gives the focus to the TextField//GEN-LAST:event_jDirectoryPathTextFieldFocusGained
   
    // Selects the text in the field
    jDirectoryPathTextField.selectAll();
}

private void jDirectoryPathTextFieldKeyTyped(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_jDirectoryPathTextFieldKeyTyped
    if (evt.getKeyChar()== KeyEvent.VK_ENTER) {//GEN-LAST:event_jDirectoryPathTextFieldKeyTyped
        _logger.debug("Directory path entered");
        performGoCancelButtonAction();
    }
}

private void jLogScrollPaneMouseMoved(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jLogScrollPaneMouseMoved
    // Event when the user crosses the log "Scroll pane" with the mouse
    // The action is to disable for a while the auto scroll down capability
    // of the scroll pane
    _remoteControl.disableAutoScrollDownTemporary();      
}//GEN-LAST:event_jLogScrollPaneMouseMoved


    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JRadioButton jCheckJpegFilesRadioButton;
    private javax.swing.ButtonGroup jChooseActionButtonGroup;
    private javax.swing.JLabel jChooseActionLabel;
    private javax.swing.JButton jChooseDirectoryButton;
    private javax.swing.JLabel jChooseDirectoryLabel;
    private javax.swing.JLabel jDigitalizationDateLabel;
    private javax.swing.JLabel jDigitalizationDateLabel2;
    private javax.swing.JTextField jDirectoryPathTextField;
    private javax.swing.JLabel jFileNameAfterLabel;
    private javax.swing.JLabel jFileNameBeforeLabel;
    private javax.swing.JButton jGoCancelButton;
    private javax.swing.JLabel jGoLabel;
    private javax.swing.JScrollPane jLogScrollPane;
    private javax.swing.JTextArea jLogTextArea;
    private javax.swing.JProgressBar jProgressBar;
    private javax.swing.JCheckBox jRecursiveCheckBox;
    private javax.swing.JRadioButton jRenameNewJpegFilesRadioButton;
    private javax.swing.JSeparator jSeparator1;
    private javax.swing.JSeparator jSeparator2;
    private javax.swing.JCheckBox jShowLabelsCheckBox;
    private javax.swing.JCheckBox jShowPicturesCheckBox;
    private javax.swing.JLabel jShowPicturesLabel;
    private javax.swing.JLabel jTitleLabel;
    // End of variables declaration//GEN-END:variables

    /**
     * Performs all necessary action when the GO/CANCEL button is pressed
     */
    private void performGoCancelButtonAction() {
         ActionTypeEnum action;
    
        // determines the state of the GO button
        if (jGoCancelButton.getText().equals(_LABEL_GO)) {
            // pressing the button means GO
            // ----------------------------
            _logger.debug("The user pressed the Go! button");    
        
            // changes the label of the button
            jGoCancelButton.setText(_LABEL_CANCEL);
        
            // determines the requested action
            action = selectedAction();
    
            if (action == ActionTypeEnum.None) {
                _logger.warn("No action selected !");
            } else {
                // starts the thread
                try {
                    new ProcessingThread(jDirectoryPathTextField.getText(),
                                        action,
                                        jRecursiveCheckBox.isSelected(),
                                        _remoteControl).start();
                }
                catch(UnknownClassException exception) {
                    _logger.error("Exception Exception_UnknownClassException caught while creating Class_processingThread : " + exception);
                }
            }
        } else {
            // pressing the button means CANCEL
            // --------------------------------
            _logger.debug("The user pressed the Cancel! button");
            
            // request the thread to stop
            _remoteControl.requestProcessingThreadToStop();
            
            // It is not time yet to set the text of the GO/CANCEL button to GO
            // The text will be reinitialized only when the processing thread will stop
            // It is time however to desactivate the GO/CANCEL button
            // The button will be reactivated when the processing thread will stop
            _remoteControl.activateGoCancelButton(false);
        }       
    }
    
    /**
     * Initializes all labels
     */
    private void initializeLabels() {
        
        // sets the label to default directory
        jDirectoryPathTextField.setText(_DEFAULT_DIRECTORY);
        _logger.info("The default directory is " + _DEFAULT_DIRECTORY);
        
        // void the text label designed to show the thumbnails (assigned to any value be visible in the frame editor)
        jShowPicturesLabel.setText(null);
        
        // void the text for the other labels (assigned to any value be visible in the frame editor)        
        reinitLabels();
        
        // set the GO label on the GO button
        jGoCancelButton.setText(_LABEL_GO);        
}
    
    /** 
     * Move the frame to the center of the window
     */
    private void moveFrameToCenter() {
        Dimension xDimension = Toolkit.getDefaultToolkit().getScreenSize();
        setLocation((xDimension.width-getWidth())/2, (xDimension.height-getHeight())/2);
    }
   
    /**
     * Change the frame to the Windows Look & Feel
     */
    private void changeToWindowsLookAndFeel() {
        
        // change the look and feel to Windows Classic Look and Feel
        try {
            UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
            SwingUtilities.updateComponentTreeUI(this);
        }
        catch (InstantiationException exception) {
            _logger.debug("Exception InstantiationException caught : " + exception);
        }
        catch (ClassNotFoundException exception) {
            _logger.debug("Exception ClassNotFoundException caught : " + exception);
        }
        catch (UnsupportedLookAndFeelException exception) {
            _logger.debug("Exception UnsupportedLookAndFeelException caught : " + exception);
        }
        catch (IllegalAccessException exception) {
            _logger.debug("Exception IllegalAccessException caught : " + exception);
        }        
    }
          
    /**
     * Indicates the action requested by the user (check boxes).
     * @return
     * the action requested by the user.
     */
    private ActionTypeEnum selectedAction() {
        ActionTypeEnum ret;
        
        if (jRenameNewJpegFilesRadioButton.isSelected()) {
            _logger.info("Rename new Jpeg files !");
            ret = ActionTypeEnum.Rename;
        } else {
            if (jCheckJpegFilesRadioButton.isSelected()) {
                _logger.info("Check Jpeg file names !");
                ret = ActionTypeEnum.Check;
            } else {
                _logger.info("No action selected !");
                ret=ActionTypeEnum.None;
            }
        }
    return ret;
    }
    
    /**
     * Disables all the commands of the frame
     * during the processing to avoid the user to start a new action
     */
    public void enableCommands(boolean myIsEnabled) {
        enableChooseDirectoryButton(myIsEnabled);
        enableDirectoryPathTextField(myIsEnabled);
        enableRenameNewJpegFilesRadioButton(myIsEnabled);
        enableRecursiveCheckBox(myIsEnabled);
    }
    
    /**
     * gets jShowPicturesLabel.
     * @return label that encloses the thumbnail.
     */
    public javax.swing.JLabel getShowPicturesLabel() {
        return jShowPicturesLabel;
    }

    /**
     * set the reference to the exchange zone
     * @param myExchangeZone
     */
    public void setExchangeZone(FrameRemoteControl myExchangeZone) {
        _remoteControl = myExchangeZone;
    }
    
    /**
     * set the text in jFileNameBeforeLabel
     * @param myText
     */
    public void setFileNameBeforeLabelText(String myText) {
        jFileNameBeforeLabel.setText(myText);
    }
    
    /**
     * set the text in jFileNameAfterLabel
     * @param myText
     */
    public void setFileNameAfterLabelText(String myText) {
        jFileNameAfterLabel.setText(myText);
    }
    
    /**
     * set the text in jTitleLabel
     * @param myText
     */
    public void setTitleLabelText(String myText) {
        jTitleLabel.setText(myText);
    }
    
    /**
     * set the text in jDigitalizationDateLabel
     * @param myText
     */
    public void setDigitalizationDateLabelText(String myText) {
        jDigitalizationDateLabel.setText(myText);
    }

    /**
     * allow to enable/disable jChooseDirectoryButton
     * @param myIsEnabled
     */
    private void enableChooseDirectoryButton (boolean myIsEnabled) {
        jChooseDirectoryButton.setEnabled(myIsEnabled);
    }
    
    /**
     * allow to enable/disable jDirectoryPathTextField
     * @param myIsEnabled
     */
    private void enableDirectoryPathTextField(boolean myIsEnabled) {
        jDirectoryPathTextField.setEnabled(myIsEnabled);
    }
    
    /**
     * allow to enable/disable jRenameNewJpegFilesRadioButton
     * @param myIsEnabled
     */
    private void enableRenameNewJpegFilesRadioButton(boolean myIsEnabled) {
        jRenameNewJpegFilesRadioButton.setEnabled(myIsEnabled);
    }
    
    /**
     * allow to enable/disable jRecursiveCheckBox
     * @param myIsEnabled
     */
    private void enableRecursiveCheckBox(boolean myIsEnabled) {
        jRecursiveCheckBox.setEnabled(myIsEnabled);
    }
    
    /**
     * indicate if jShowPicturesCheckBox is checked
     * @return status of the checkbox that indicates if the thumbnail of the file
     * that is being processed must be shown
     */
    public boolean isShowPicturesCheckBoxSelected() {
        return jShowPicturesCheckBox.isSelected();
    }
    
    /**
     * indicates if jShowLabelsCheckBox is checked
     * @return status of the checkbox that indicates if the details of the file
     * that is being processed must be shown
     */
    public boolean isShowLabelsCheckBoxSelected() {
        return jShowLabelsCheckBox.isSelected();
    }

    /**
     * set the string in the progress bar
     * @param myMsg
     */
    public void setProgressBarString(String myMsg) {
        jProgressBar.setString(myMsg);
    }
    
    /**
     * set the painting in the progress bar
     * @param myIsPainted
     */
    public void setProgressBarStringPainted(boolean myIsPainted) {
        jProgressBar.setStringPainted(myIsPainted);
    }
    
    /**
     * set the progress bar in indeterminate mode
     * @param myIsIndeterminate
     */
    public void setProgressBarIndeterminate(boolean myIsIndeterminate) {
        jProgressBar.setIndeterminate(myIsIndeterminate);
    }
    
    /**
     * set the progress value in the progress bar
     * @param myValue
     */
    public void setProgressBarValue(int myValue) {
        jProgressBar.setValue(myValue);
    }
    
    /**
     * Reinits the progress bar
     */
    public void reinitProgressBar() {
        jProgressBar.setStringPainted(false);
        jProgressBar.setValue(0);
    }
    /**
     * gets the root pane.
     * @return rootPane
     */
    public javax.swing.JRootPane getRootPane() {
        return rootPane;
    }
    
    /**
     * set the image icon in jShowPictureLabel
     * @param myImageIcon
     */
    public void setShowPicturesLabelIcon(ImageIcon myImageIcon) {
        jShowPicturesLabel.setIcon(myImageIcon);
    }

    /**
     * gets the width of the jShowPicturesLabel.
     * @return label that encloses the thumbnail.
     */
    public int getShowPicturesLabelWidth() {
        return jShowPicturesLabel.getWidth();
    }

    /**
     * gets the height of the jShowPicturesLabel
     * @return height of the label that encloses the thumbnail.
     */
    public int getShowPicturesLabelHeight() {
        return jShowPicturesLabel.getHeight();
    }
    
    /**
     * Set the text of the GO/CANCEL button
     * @param myString The text to set to the button
     */
    public void reinitGoCancelButton() {
        jGoCancelButton.setText(_LABEL_GO);
    }
    
    /**
     * Activates or desactivates the GO/CANCEL button
     * @param myActivation indicates if the button must be activated (true) or desactivated (false)
     */
    public void activateGoCancelButton(boolean myActivation) {
        jGoCancelButton.setEnabled(myActivation);
    }
    
    /**
     * reinitialize the labels describing the file before/after renaming
     */
    public void reinitLabels() {
        jFileNameBeforeLabel.setText(null);
        jTitleLabel.setText(null);
        jDigitalizationDateLabel.setText(null);
        jFileNameAfterLabel.setText(null);    
    }
        
    /**
     * Sets the remote control attribute and registers the frame in the remote 
     * control
     * @param myRemoteControl
     * The remote control to set as attribute
     */
    private void setRemoteControl(FrameRemoteControl myRemoteControl) 
        throws UnknownClassException {
        // sets the attribute
        _remoteControl = myRemoteControl;
        
        // registers the frame in the remote control
        _remoteControl.register(this);
    }
    
    /**
     * change the shape of the border of the text area
     * depending wether the scroll down is enabled or disabled
     * @param isTransient
     */
    public void changeBorderToTransient(boolean isTransient) {
        if (isTransient) {
            _logger.debug("set border in transient");
            jLogScrollPane.setViewportBorder(javax.swing.BorderFactory.createMatteBorder(1, 1, 1, 1, new java.awt.Color(204, 0, 51)));
        } else {
            _logger.debug("reinit border");
            jLogScrollPane.setViewportBorder(null);
        }
    }
}
